package com.cratos.xxgram.platf.sysnotice;

import java.util.Arrays;

import javax.annotation.Resource;

import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.service.RetResult;
import org.redkale.source.ColumnValue;
import org.redkale.source.FilterExpress;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.AnyValue;
import org.redkale.util.Comment;
import org.redkale.util.Utility;

import com.cratos.xxgram.platf.base.BaseService;
import com.cratos.xxgram.platf.base.RetCodes;
import com.cratos.xxgram.platf.base.UserInfo;
import com.cratos.xxgram.platf.message.BasicContent.SysNoticeMessage;
import com.cratos.xxgram.platf.message.MessageRecord;
import com.cratos.xxgram.platf.message.MessageService;
import static com.cratos.xxgram.platf.sysnotice.SystemNotice.USER_CYCLE_All;
import com.cratos.xxgram.platf.user.UserDetail;
import java.util.List;


@RestService(name = "systemnotice", comment = "系统公告查询")
public class SystemNoticeService extends BaseService {

	@Resource
	private MessageService messageService;

	@Override
	public void init(AnyValue config) {
		// TODO Auto-generated method stub
		super.init(config);
	}
	
	@RestMapping(name = "createSystemNotice", auth = true, comment = "创建系统公告")
	public RetResult createSystemNotice(int userid, SystemNotice bean) {
		long now = System.currentTimeMillis();
		bean.setCreatetime(now);
		bean.setSysnoticeid(userid + "-" + Utility.format36time(now));
		source.insert(bean);
		// 只有是开启的用户才会发送相关消息
                
                FilterNode appOnlineNode = FilterNode
                                .create("onlineterminal", FilterExpress.EQUAL, 1)
                                .or("onlineterminal", FilterExpress.EQUAL, 3);
                  
                java.util.Set<Integer> useridSet = source.queryColumnSet("userid", UserDetail.class, appOnlineNode);
                logger.finest("createSystemNotice ======" + bean);
                {
			SysNoticeMessage message = new SysNoticeMessage();
			message.setNotice(bean);
			MessageRecord messageRecord = new MessageRecord();
			/**
			 * 查询所有的系统用户 发送相关消息
			 */
			messageRecord.setContent(JsonConvert.root().convertTo(message));
			messageRecord.setMsgtype(SysNoticeMessage.TYPE);
			messageRecord.setFromid(UserInfo.USER_MSG_SYSTEM.getUserid());
			messageRecord.setCreatetime(System.currentTimeMillis());
			messageRecord.setMsgkind(MessageRecord.MSG_KIND_SYSTEM);
			String time36 = Utility.format36time(System.currentTimeMillis());
                        boolean all = (bean.getNoticetarget() == SystemNotice.USER_CYCLE_All);
                        logger.finest("createSystemNotice bean.isAllUser() ======" + all);
                        List<UserDetail> datas = source.queryList(UserDetail.class, (org.redkale.source.FilterBean) null);
                        logger.finest("createSystemNotice datas) ======" + (datas.isEmpty() ? 0 : datas.size()));
                        if (!datas.isEmpty()) {
                             logger.finest("createSystemNotice bean.target() ======" + all);
                             Thread th = new Thread(() -> {
                                try {
                                  sortUsers(datas);
                                  logger.fine("createSystemNotice datas) 111111" + (datas.isEmpty() ? 0 : datas.size()));
                                    datas.forEach(uid -> {
                                        logger.finest("createSystemNotice uid ======" + uid + ",=== " + uid);
                                        try {
                                              if (uid.getUsercycle() == bean.getNoticetarget() || bean.getNoticetarget() == USER_CYCLE_All) {
                                                MessageRecord record = messageRecord.copy();
                                                int user = uid.getUserid();
                                                record.setTargetid(user);
                                                record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + user + "-" + time36);
                                                logger.finest("createSystemNotice uid ======" + uid);
                                                insertQueue.add(bean.copySystemUserNotice(user));
                                                insertQueue.add(record); // 保存入库
                                                messageService.sendNotifyMessageWithSaveOss(record, Arrays.asList(user), useridSet.contains(user));
                                            }
                                        } catch (Exception error) {
                                            error.printStackTrace();
                                             logger.finest("error ...... ======" + error.getMessage());
                                        }
                                    });
                              }catch(Exception e) {
                                   logger.finest("error ...... ======" + e.getMessage());
                              }
                              });
                              th.setDaemon(true);
                              th.start();
                        }
                       
		}
		return RetResult.success();
	}


        /**
         * 排序发送先后顺序
         * @param rows 
         */
        public static void sortUsers(List<UserDetail>  rows) {
            java.util.Collections.sort(rows, (UserDetail user1, UserDetail user2) -> {
                   if(user1.getOnlineterminal() > user2.getOnlineterminal()) {
                        return -1;
                    } else if(user1.getOnlineterminal() == user2.getOnlineterminal()) {
                        return 0;
                    } else {
                        return 1;
                    }
            });
        }
        
        
	@Comment("更新狀態")
	public RetResult updateNoticeStatus(String sysnoticeid, short status) {
		SystemNotice notice = source.find(SystemNotice.class, sysnoticeid);
		if (notice == null) {
			return RetCodes.retResult(RetCodes.RET_PARAMS_ILLEGAL);
		}
		if (notice.getStatus() == status) {
			return RetResult.success();
		}
		notice.setStatus(status);
		source.updateColumn(SystemNotice.class, notice.getSysnoticeid(), "status", status);
		source.updateColumn(SystemUserNotice.class, FilterNode.create("sysnoticeid", FilterExpress.EQUAL, notice.getSysnoticeid()), ColumnValue.mov("status", status));
                java.util.Set<Integer> userSet = source.queryColumnSet("userid", SystemUserNotice.class, FilterNode.create("sysnoticeid", FilterExpress.EQUAL, notice.getSysnoticeid()));
                SysNoticeMessage message = new SysNoticeMessage();
                message.setNotice(notice);
                MessageRecord messageRecord = new MessageRecord();
		/**
		 * 查询所有的系统用户 发送相关消息
		 */
                messageRecord.setContent(JsonConvert.root().convertTo(message));
                messageRecord.setMsgtype(SysNoticeMessage.TYPE);
                messageRecord.setFromid(UserInfo.USER_MSG_SYSTEM.getUserid());
                messageRecord.setCreatetime(System.currentTimeMillis());
                messageRecord.setMsgkind(MessageRecord.MSG_KIND_SYSTEM);
                
                // 开启状态不做处理
                //if (status == SystemNotice.CLOSE_STATUS) 
                {
                    Flipper  flipper = new Flipper();
                    flipper.sort("createtime desc");
                    FilterNode appOnlineNode = FilterNode
                                .create("onlineterminal", FilterExpress.EQUAL, 1)
                                .or("onlineterminal", FilterExpress.EQUAL, 3);

                    FilterNode webOnlineNode = FilterNode
                                .create("onlineterminal", FilterExpress.EQUAL, 2);
                   
                    List<UserDetail> webOnlineUsers = source.queryList(UserDetail.class, webOnlineNode);
                    // 查询App 在线用户 发送消息
                     String time36 = Utility.format36time(System.currentTimeMillis());
                    if (notice.getNoticetarget() == 4) {
                            source.queryColumnSetAsync("userid", UserDetail.class, appOnlineNode)
                                            .whenComplete((rows, e) -> {
                                                    logger.finest("rows =====>>>" + JsonConvert.root().convertTo(rows));
                                                    rows.forEach(uid -> {
                                                           boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                                           if (userSet.contains(uid) && onLine) {
                                                                MessageRecord record = messageRecord.copy();
                                                                Integer user = (Integer) uid;

                                                                SysNoticeMessage msg = new SysNoticeMessage();
                                                                msg.setStatus(SysNoticeMessage.CLOSE_STATUS);
                                                                msg.setNotice(notice);
                                                                List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                                                .create("userid", FilterExpress.EQUAL, uid)
                                                                .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                                                if (!dataSet.isEmpty()) {
                                                                     msg = msg.copyLastNotice(dataSet.get(0));
                                                                }
                                                                record.setContent(JsonConvert.root().convertTo(msg));
                                                                record.setTargetid(user);
                                                                record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + user.intValue() + "-" + time36);
                                                                messageService.sendNotifyMessageOnly(record, Arrays.asList(user));
                                                                FilterNode node = FilterNode.create("status", FilterExpress.EQUAL, SystemNotice.CLOSE_STATUS).and("userid", FilterExpress.EQUAL, uid);
                                                                source.delete(SystemUserNotice.class, node);
                                                           }
                                                           
                                                    });

                                            });
                            
                           
                             // web
                            new Thread(() -> {
                                 webOnlineUsers.forEach(userInfo -> {
                                int uid = userInfo.getUserid();
                                 boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                if (userSet.contains(uid) && onLine) {
                                     MessageRecord record = messageRecord.copy();
                                     SysNoticeMessage msg = new SysNoticeMessage();
                                     msg.setStatus(SysNoticeMessage.CLOSE_STATUS);
                                     msg.setNotice(notice);
                                     List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                     .create("userid", FilterExpress.EQUAL, uid)
                                     .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                     if (!dataSet.isEmpty()) {
                                          msg = msg.copyLastNotice(dataSet.get(0));
                                     }
                                     record.setContent(JsonConvert.root().convertTo(msg));
                                     record.setTargetid(uid);
                                     record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + uid + "-" + time36);
                                     messageService.sendNotifyMessageOnly(record, Arrays.asList(uid));
                                }
                            });
                                
                            }).start();
                    }

                    if (notice.isNewUser()) {
                            source.queryColumnSetAsync("userid", UserDetail.class,
                                            FilterNode.create("usercycle", FilterExpress.EQUAL, UserInfo.USER_CYCLE_NEW).and(appOnlineNode))
                                            .whenComplete((rows, e) -> {
                                                    logger.finest("rows =====>>>" + JsonConvert.root().convertTo(rows));
                                                    rows.forEach(uid -> {
                                                         boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                                         if (userSet.contains(uid) && onLine) {
                                                             MessageRecord record = messageRecord.copy();
                                                            Integer user = (Integer) uid;


                                                            SysNoticeMessage msg = new SysNoticeMessage();
                                                            msg.setNotice(notice);
                                                            msg.setStatus(SysNoticeMessage.CLOSE_STATUS);
                                                            List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                                            .create("userid", FilterExpress.EQUAL, uid)
                                                            .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                                            if (!dataSet.isEmpty()) {
                                                                 msg = msg.copyLastNotice(dataSet.get(0));
                                                            }
                                                            record.setContent(JsonConvert.root().convertTo(msg));


                                                            record.setTargetid(user);
                                                            record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + user.intValue() + "-" + time36);
                                                            messageService.sendNotifyMessageOnly(record, Arrays.asList(user));
                                                            FilterNode node = FilterNode.create("status", FilterExpress.EQUAL, SystemNotice.CLOSE_STATUS).and("userid", FilterExpress.EQUAL, uid);
                                                            source.delete(SystemUserNotice.class, node);
                                                         }
                                                            
                                                    });

                                            });
                            
                            //web
                            new Thread(() -> {
                                 webOnlineUsers.forEach(userInfo -> {
                                 if (userInfo.getUsercycle() == 1) {
                                      int uid = userInfo.getUserid();
                                      boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                    if (userSet.contains(uid) && onLine) {
                                         MessageRecord record = messageRecord.copy();
                                         SysNoticeMessage msg = new SysNoticeMessage();
                                         msg.setStatus(SysNoticeMessage.CLOSE_STATUS);
                                         msg.setNotice(notice);
                                         List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                         .create("userid", FilterExpress.EQUAL, uid)
                                         .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                         if (!dataSet.isEmpty()) {
                                              msg = msg.copyLastNotice(dataSet.get(0));
                                         }
                                         record.setContent(JsonConvert.root().convertTo(msg));
                                         record.setTargetid(uid);
                                         record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + uid + "-" + time36);
                                         messageService.sendNotifyMessageOnly(record, Arrays.asList(uid));
                                    }
                                 }
                               
                            });
                            }).start();
                            
                    }

                    if (notice.isOldUser()) {
                            source.queryColumnSetAsync("userid", UserDetail.class,
                                            FilterNode.create("usercycle", FilterExpress.EQUAL, UserInfo.USER_CYCLE_OLD)
                                                    .and(appOnlineNode))
                                            .whenComplete((rows, e) -> {
                                                   logger.finest("rows =====>>>" + JsonConvert.root().convertTo(rows));
                                                    rows.forEach(uid -> {
                                                            MessageRecord record = messageRecord.copy();
                                                            Integer user = (Integer) uid;
                                                            boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                                            if (userSet.contains(uid) && onLine) {
                                                                 // 组装新消息
                                                                SysNoticeMessage msg = new SysNoticeMessage();
                                                                msg.setNotice(notice);
                                                                msg.setStatus(SysNoticeMessage.CLOSE_STATUS);

                                                                List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                                                .create("userid", FilterExpress.EQUAL, uid)
                                                                .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                                                if (!dataSet.isEmpty()) {
                                                                     msg = msg.copyLastNotice(dataSet.get(0));
                                                                }
                                                                record.setContent(JsonConvert.root().convertTo(msg));
                                                                record.setTargetid(user);
                                                                record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + user.intValue() + "-" + time36);
                                                                messageService.sendNotifyMessageOnly(record, Arrays.asList(user));
                                                                FilterNode node = FilterNode.create("status", FilterExpress.EQUAL, SystemNotice.CLOSE_STATUS).and("userid", FilterExpress.EQUAL, uid);
                                                                source.delete(SystemUserNotice.class, node);
                                                            }
                                                    });
                                            });
                            
                            //web
                            new Thread(() -> {
                                webOnlineUsers.forEach(userInfo -> {
                                               if (userInfo.getUsercycle() == 2) {
                                                    int uid = userInfo.getUserid();
                                                    boolean onLine = webSocketNode.existsWebSocket(uid).join();
                                                  if (userSet.contains(uid) && onLine) {
                                                       MessageRecord record = messageRecord.copy();
                                                       SysNoticeMessage msg = new SysNoticeMessage();
                                                       msg.setStatus(SysNoticeMessage.CLOSE_STATUS);
                                                       msg.setNotice(notice);
                                                       List<SystemUserNotice> dataSet =  source.queryList(SystemUserNotice.class,flipper, FilterNode
                                                       .create("userid", FilterExpress.EQUAL, uid)
                                                       .and("status", FilterExpress.EQUAL, SystemNotice.OPEN_STATUS));
                                                       if (!dataSet.isEmpty()) {
                                                            msg = msg.copyLastNotice(dataSet.get(0));
                                                       }
                                                       record.setContent(JsonConvert.root().convertTo(msg));
                                                       record.setTargetid(uid);
                                                       record.setMessageid(UserInfo.USER_MSG_SYSTEM.getUserid() + "-" + uid + "-" + time36);
                                                       messageService.sendNotifyMessageOnly(record, Arrays.asList(uid));
                                                  }
                                               }
                                          });
                            }).start();
                                       
                    }
                }
                
		return RetResult.success();
	}

	public static void main(String[] args) throws Exception {
//		SystemNotice bean = new SystemNotice();
//		bean.setCreatetime(System.currentTimeMillis());
//		bean.setSysnoticeid(300000001 + "-" + Utility.formatTime(System.currentTimeMillis()));
//		bean.setStatus(SystemNotice.OPEN_STATUS);
//		bean.setNoticetarget(SystemNotice.USER_CYCLE_All);
		 SystemNoticeService service = org.redkale.boot.Application.singleton(SystemNoticeService.class);
		 UserInfo user = new UserInfo(300000001);
                SystemNotice notice = new SystemNotice();
                notice.setStatus(SystemNotice.OPEN_STATUS);
                notice.setNoticetarget(SystemNotice.USER_CYCLE_All);
                notice = JsonConvert.root().convertFrom(SystemNotice.class, "{\"allUser\":true,\"content\":\"4月15日是全民国家安全教育日，贯彻总体国家安全观，坚持人民安全、政治安全、国家利益至上的有机统一，依法自觉履行维护国家安全的责任与义务。\\n\\n\",\"createtime\":1586914750014,\"noticetarget\":4,\"openStatus\":true,\"status\":10,\"sysnoticeid\":\"1000001-0k90o2hq6\",\"title\":\"测试004\"}");
                 service.createSystemNotice(1, notice);
                 Thread.sleep(1000 * 20);
//		 RetResult result = service.loadSystemNotices(user, null, null);
//		 System.out.println(result);
////		 service.createSystemNotice(1, bean);
//		 Thread.sleep(1000 * 10);
	//		SysNoticeMessage message = new SysNoticeMessage();
	//		message.setNotice(bean);
	//		MessageRecord messageRecord = new MessageRecord();
	//
	//		messageRecord.setContent(JsonConvert.root().convertTo(message));
	//		messageRecord.setMsgtype(SysNoticeMessage.TYPE);
	//		messageRecord.setFromid(-1);
	//		messageRecord.setCreatetime(System.currentTimeMillis());
	//		messageRecord.setMsgkind(MessageRecord.MSG_KIND_SYSTEM);
	//		messageRecord.setMessageid(-1 + "-" + Utility.format36time(System.currentTimeMillis()));
	//		System.out.println(messageRecord.toString());
	}

	@Deprecated(since = "修改查询表数据从历史表中获取")
//	@RestMapping(name = "loadSystemNotices", auth = true, comment = "查询系统公告")
	public RetResult loadSystemNoticesBak(UserInfo userinfo, Flipper flipper, SystemNoticeBean bean) {
		if (flipper == null) {
			flipper = new Flipper();
		}
		
		if(bean == null) bean = new SystemNoticeBean();
		flipper.sort("createtime desc");
		return RetResult.success(source.querySheet(SystemNotice.class,
					flipper,
					FilterNode.create("createtime", FilterExpress.GREATERTHANOREQUALTO, userinfo.getRytime())
							  .and("status", FilterExpress.EQUAL, bean.getStatus())
							  .and(FilterNode.create("noticetarget", FilterExpress.EQUAL, userinfo.getUsercycle())
									  	.or("noticetarget", FilterExpress.EQUAL, SystemNotice.USER_CYCLE_All))
							  ));
	}
	
	
	
	@RestMapping(name = "loadSystemNotices", auth = true, comment = "查询系统公告")
	public RetResult loadSystemNotices(UserInfo userinfo, Flipper flipper, SystemNoticeBean bean) {
		if (flipper == null) {
			flipper = new Flipper(Integer.MAX_VALUE);
		}
		if (bean == null) bean = new SystemNoticeBean();
		flipper.sort("createtime desc");
		return RetResult.success(source.querySheet(SystemUserNotice.class,flipper, FilterNode
					.create("userid", FilterExpress.EQUAL, userinfo.getUserid())
					.and("status", FilterExpress.EQUAL, bean.getStatus())));
	}
}
